#include <iostream>
#include <string>
#include <vector>
using namespace std;
//实验内容：
//设计一个Date类，包含：
//1、私有实例属性年月日。
//2、私有静态属性maxYear和minYear，
//3、公有静态方法设置maxYear和minYear的值，如：
//static void SetMaxYear(int maxY)
//{
//    maxYear = maxY;
//}

class Date
{
    friend class StudentList;
public:
    Date(int year = 0, int month = 0, int day = 0);

    static void SetMaxYear(int maxY) { _maxYear = maxY; }
    static void SetMinYear(int minY) { _minYear = minY; }
private:
    int _year;
    int _month;
    int _day;

    static int _maxYear;
    static int _minYear;
};
int Date::_maxYear = 0;
int Date::_minYear = 0;

Date::Date(int year, int month, int day)
    :_year(year)
    ,_month(month)
    ,_day(day)
{
    if (_year > _maxYear) _year = _maxYear;
    if (_year < _minYear) _year = _minYear;
}

//设计一个Student类，数据成员包含int类型的学号、string类型的姓名、Date类型的生日。

class Student
{
    friend class StudentList;
public:
    Student(){}
    Student(int,const string&, const Date&);
    Student(const Student&);
    Student& operator=(Student);
    void swap(Student&);
private:
    int _num;
    string _name;
    Date _date;
};

Student::Student(int num, const string& str, const Date& date)
    :_num(num)
    ,_name(str)
    ,_date(date)
{}
Student::Student(const Student& s)
    :_num(s._num)
    , _name(s._name)
    ,_date(s._date)
{}
Student& Student::operator=(Student s)
{
    swap(s);
    return *this;
}
void Student::swap(Student& s)
{
    std::swap(this->_date, s._date);
    std::swap(this->_name, s._name);
    std::swap(this->_num, s._num);
}
//设计一个StudentList类，包含：
//1、私有属性：Student对象数组，可声明大小为100，即保存不超过100个元素
//2、私有属性：数组中实际保存的元素个数
//3、公有方法：AddStudent(Student stu)，将传入的形参stu增加到数组中
//4、公有方法：DeleteStudent(int num)，根据传入的学号num从数组中删除学生
//5、公有方法：StudentList GetStudent(int year1, int year2)，其中：
//形参：包括两个int型值year1和year2，并且year1 <= year2
//功能：查找Student对象数组中所有出生年在year1和year2之间（含year1和year2）的学生
//返回值：返回符合条件的学生，用一个StudentList对象返回
//6、公有方法：Print()，输出Student对象数组中所有学生的信息，包括学号、姓名、生日（年月日）。
//如果数组中有多个元素（学生），则一个元素输出一行。如果数组中没有元素，则输出“No result.”

class StudentList
{
public:
    void AddStudent(const Student&);
    void DeleteStudent(int num);
    StudentList GetStudent(int year1, int year2);
    void Print();
private:
    vector<Student> _studentList = vector<Student>(100);
    int _size = 0;
};

void StudentList::AddStudent(const Student& stu)
{
    _studentList[_size++] = stu;
}
void StudentList::DeleteStudent(int num)
{
    for (int i = 0; i < _size; i++)
        if (_studentList[i]._num == num)
            _studentList[i] = _studentList[--_size];
}
StudentList StudentList::GetStudent(int year1, int year2)
{
    StudentList ret;
    for (auto& e : _studentList)
        if (e._date._year >= year1 && e._date._year <= year2)
            ret.AddStudent(e);
    return ret;
}
void StudentList::Print()
{
    if (!_size)
    {
        cout << "No result." << endl;
        return;
    }
    for (int i = 0; i < _size; i++)
    {
        const auto& e = _studentList[i];
        cout << e._num << ' ' << e._name << ' ' << e._date._year << ' ' << e._date._month << ' ' << e._date._day << endl;
    }
}

//以上三个类只规定了必要的几个方法，其它的方法请自行设计，包括构造函数。

//下面解释Date类中静态成员maxYear和minYear的作用：
//由于学生入学年龄有限制，比如，规定大学生必须在13岁到45岁之间。因此，如果现在是2020年，则入学学生中，maxYear为2020 - 13 = 2007，minYear为2020 - 45 = 1975。
//程序运行时，首先由用户输入maxYear和minYear，并存储到Date类中。
//当创建Student对象时，如果发现学生的出生年份大于maxYear，则设置该学生的出生年为maxYear；如果发现学生的出生年份小于minYear，则设置该学生的出生年为minYear。
//输入学生生日时，不需要检查日期是否合法。

//main函数可参考如下代码：

int main()
{
    int num, birthYear, birthMonth, birthDay;
    int maxYear, minYear, year1, year2;
    int op;
    string name;
    StudentList sl;
    Student stu;

    cin >> maxYear >> minYear;
    Date::SetMaxYear(maxYear);
    Date::SetMinYear(minYear);
    while (cin >> op)
    {
        switch (op)
        {
        case 1:
            cin >> num >> name >> birthYear >> birthMonth >> birthDay;
            stu = Student(num, name, Date(birthYear, birthMonth, birthDay));
            sl.AddStudent(stu);
            break;
        case 2:
            cin >> num;
            sl.DeleteStudent(num);
            break;
        case 3:
            cin >> year1 >> year2;
            StudentList temp = sl.GetStudent(year1, year2);
            temp.Print();
            break;
        }
    }
    return 0;
}
